{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d9a0d35",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import math\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch.autograd import Variable\n",
    "\n",
    "import torch.utils.data.dataset as Dataset\n",
    "\n",
    "from torch.utils.data import DataLoader\n",
    "import torchvision.transforms as transforms\n",
    "\n",
    "from PIL import Image\n",
    "import torchvision.models as models\n",
    "\n",
    "import os\n",
    "os.environ[\"KMP_DUPLICATE_LIB_OK\"]  =  \"TRUE\"\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from libtiff import TIFF\n",
    "\n",
    "from CBAM_Attention_Module import AttachAttentionModule"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a16664e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "class SRNet_dataset(Dataset.Dataset):\n",
    "    def __init__(self,csv_dir):\n",
    "        self.csv_dir = csv_dir\n",
    "       \n",
    "        self.names_list = []\n",
    "        self.size = 0\n",
    "        self.transform = transforms.ToTensor()\n",
    "        #把csv文件中的路径读进来\n",
    "        if not os.path.isfile(self.csv_dir):\n",
    "            print(self.csv_dir + ':text file does not exist!')\n",
    "        file = open(self.csv_dir)\n",
    "        for f in file:\n",
    "            self.names_list.append(f)\n",
    "            self.size += 1\n",
    "    \n",
    "    def __len__(self):\n",
    "        return self.size\n",
    "    \n",
    "    def __getitem__(self,idx):\n",
    "        #读取图像路径并打开图像\n",
    "        image_path = self.names_list[idx].split(',')[0]\n",
    "        img = TIFF.open(image_path,mode='r')\n",
    "        #print(type(img))  # <class 'libtiff.libtiff_ctypes.TIFF'>\n",
    "        image = img.read_image() \n",
    "        \n",
    "        #读取标签路径并打开标签图像\n",
    "        label_path = self.names_list[idx].split(',')[1]\n",
    "        label = Image.open(label_path)\n",
    "        \n",
    "        pic_path = self.names_list[idx].split(',')[2].strip('\\n')\n",
    "        pic = Image.open(pic_path)\n",
    "\n",
    "        #函数返回一个字典类型的数据，里面包括了图像和标签，并将它们转为tensor形式\n",
    "        sample = {'image':image,'label':label, 'pic':pic}\n",
    "        sample['image'] = self.transform(sample['image'])\n",
    "        sample['label'] = torch.from_numpy(np.array(sample['label']))\n",
    "        sample['pic'] = self.transform(sample['pic'])\n",
    "\n",
    "        return sample"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88b84cbb",
   "metadata": {},
   "outputs": [],
   "source": [
    "class focal_loss(nn.Module):\n",
    "    def __init__(self, model, alpha, gamma=0, num_classes = 2, size_average=True):\n",
    "        super(focal_loss,self).__init__()\n",
    "        if model == 1:\n",
    "            self.model = 21.05\n",
    "        if model == 2:\n",
    "            self.model = 4.52\n",
    "        if model == 3:\n",
    "            self.model = 8.31\n",
    "        self.size_average = size_average\n",
    "        if isinstance(alpha,list):\n",
    "            assert len(alpha)==num_classes   # α可以以list方式输入,size:[num_classes] 用于对不同类别精细地赋予权重\n",
    "            print(\" --- Focal_loss alpha = {}, 将对每一类权重进行精细化赋值 --- \".format(alpha))\n",
    "            self.alpha = torch.Tensor(alpha)\n",
    "        else:\n",
    "            assert alpha<1   #如果α为一个常数,则降低第一类的影响,在目标检测中为第一类\n",
    "            \n",
    "            print(alpha)\n",
    "            print(self.model)\n",
    "            \n",
    "            self.alpha = torch.zeros(num_classes)\n",
    "            self.alpha[0] += alpha\n",
    "            self.alpha[1:] += (1-alpha) # α 最终为 [ α, 1-α, 1-α, 1-α, 1-α, ...] size:[num_classes]\n",
    "\n",
    "        self.gamma = gamma\n",
    "\n",
    "    def forward(self, preds, labels):\n",
    "        # assert preds.dim()==2 and labels.dim()==1\n",
    "        \n",
    "        preds_logsoft = F.log_softmax(preds, dim=1) # log_softmax\n",
    "        #print(preds_logsoft)\n",
    "        \n",
    "        preds_softmax = torch.exp(preds_logsoft)    # softmax\n",
    "        #print(preds_softmax)\n",
    "\n",
    "        preds_softmax = preds_softmax.gather(1,labels.view(-1,1))   # 这部分实现nll_loss ( crossempty = log_softmax + nll )\n",
    "        #print(preds_softmax)\n",
    "        \n",
    "        preds_logsoft = preds_logsoft.gather(1,labels.view(-1,1))\n",
    "        #print(preds_logsoft)\n",
    "        self.alpha = self.alpha.cuda()\n",
    "        self.alpha = self.alpha.gather(0,labels.view(-1).cuda()).cuda()\n",
    "        #print(self.alpha)\n",
    "        \n",
    "        loss = -torch.mul(torch.pow((1-preds_softmax), self.gamma), preds_logsoft)  # torch.pow((1-preds_softmax), self.gamma) 为focal loss中 (1-pt)**γ\n",
    "\n",
    "        #print(loss)\n",
    "        loss = torch.mul(self.alpha, loss.t())\n",
    "        #print(loss)\n",
    "        \n",
    "        \n",
    "        if self.size_average:\n",
    "            loss = loss.mean() * self.model\n",
    "        else:\n",
    "            loss = loss.sum() * self.model\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "26cd1bd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Srnet(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Srnet, self).__init__()\n",
    "        # Layer 1\n",
    "        self.layer1 = nn.Conv2d(in_channels=12, out_channels=64,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn1 = nn.BatchNorm2d(64)\n",
    "        self.attention1 = AttachAttentionModule(64)\n",
    "        \n",
    "        # Layer 2\n",
    "        self.layer2 = nn.Conv2d(in_channels=64, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn2 = nn.BatchNorm2d(16)\n",
    "        self.attention2 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 3\n",
    "        self.layer31 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn31 = nn.BatchNorm2d(16)\n",
    "        self.layer32 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn32 = nn.BatchNorm2d(16)\n",
    "        self.attention3 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 4\n",
    "        self.layer41 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn41 = nn.BatchNorm2d(16)\n",
    "        self.layer42 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn42 = nn.BatchNorm2d(16)\n",
    "        self.attention4 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 5\n",
    "        self.layer51 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn51 = nn.BatchNorm2d(16)\n",
    "        self.layer52 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn52 = nn.BatchNorm2d(16)\n",
    "        self.attention5 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 6\n",
    "        self.layer61 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn61 = nn.BatchNorm2d(16)\n",
    "        self.layer62 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn62 = nn.BatchNorm2d(16)\n",
    "        self.attention6 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 7\n",
    "        self.layer71 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn71 = nn.BatchNorm2d(16)\n",
    "        self.layer72 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn72 = nn.BatchNorm2d(16)\n",
    "        self.attention7 = AttachAttentionModule(16)\n",
    "        \n",
    "        # Layer 8\n",
    "        self.layer81 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=1, stride=2, padding=0, bias=False)\n",
    "        self.bn81 = nn.BatchNorm2d(16)\n",
    "        self.layer82 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn82 = nn.BatchNorm2d(16)\n",
    "        self.layer83 = nn.Conv2d(in_channels=16, out_channels=16,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn83 = nn.BatchNorm2d(16)\n",
    "        self.pool1 = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)\n",
    "        \n",
    "        # Layer 9\n",
    "        self.layer91 = nn.Conv2d(in_channels=16, out_channels=64,\n",
    "            kernel_size=1, stride=2, padding=0, bias=False)\n",
    "        self.bn91 = nn.BatchNorm2d(64)\n",
    "        self.layer92 = nn.Conv2d(in_channels=16, out_channels=64,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn92 = nn.BatchNorm2d(64)\n",
    "        self.layer93 = nn.Conv2d(in_channels=64, out_channels=64,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn93 = nn.BatchNorm2d(64)\n",
    "        self.pool2 = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)\n",
    "        \n",
    "        # Layer 10\n",
    "        self.layer101 = nn.Conv2d(in_channels=64, out_channels=128,\n",
    "            kernel_size=1, stride=2, padding=0, bias=False)\n",
    "        self.bn101 = nn.BatchNorm2d(128)\n",
    "        self.layer102 = nn.Conv2d(in_channels=64, out_channels=128,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn102 = nn.BatchNorm2d(128)\n",
    "        self.layer103 = nn.Conv2d(in_channels=128, out_channels=128,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn103 = nn.BatchNorm2d(128)\n",
    "        self.pool3 = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)\n",
    "        \n",
    "        # Layer 11\n",
    "        self.layer111 = nn.Conv2d(in_channels=128, out_channels=256,\n",
    "            kernel_size=1, stride=2, padding=0, bias=False)\n",
    "        self.bn111 = nn.BatchNorm2d(256)\n",
    "        self.layer112 = nn.Conv2d(in_channels=128, out_channels=256,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn112 = nn.BatchNorm2d(256)\n",
    "        self.layer113 = nn.Conv2d(in_channels=256, out_channels=256,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn113 = nn.BatchNorm2d(256)\n",
    "        self.pool3 = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)\n",
    "\n",
    "        # Layer 12\n",
    "        self.layer121 = nn.Conv2d(in_channels=256, out_channels=512,\n",
    "            kernel_size=3, stride=2, padding=1, bias=False)\n",
    "        self.bn121 = nn.BatchNorm2d(512)\n",
    "        self.layer122 = nn.Conv2d(in_channels=512, out_channels=512,\n",
    "            kernel_size=3, stride=1, padding=1, bias=False)\n",
    "        self.bn122 = nn.BatchNorm2d(512)\n",
    "        \n",
    "        self.deconv2 = nn.ConvTranspose2d(in_channels=512, out_channels=512, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)\n",
    "        self.debn2   = nn.BatchNorm2d(512)\n",
    "        #倒数2层的反卷积[1/16 --> 1/8]\n",
    "        self.deconv1 = nn.ConvTranspose2d(in_channels=512, out_channels=256, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)\n",
    "        self.debn1   = nn.BatchNorm2d(256)\n",
    "        #倒数3层的反卷积[1/8 --> 1/4]\n",
    "        self.deconv0_1 = nn.ConvTranspose2d(in_channels=256, out_channels=128, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)\n",
    "        self.debn0_1   = nn.BatchNorm2d(128)\n",
    "        #倒数4层的反卷积[1/4 --> 1/2]\n",
    "        self.deconv0_2 = nn.ConvTranspose2d(in_channels=128, out_channels=64, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)\n",
    "        self.debn0_2   = nn.BatchNorm2d(64)\n",
    "        #倒数5层的反卷积[1/2 --> 1/1]\n",
    "        self.deconv0_3 = nn.ConvTranspose2d(in_channels=64, out_channels=32, kernel_size=3, stride=2, padding=1, dilation=1, output_padding=1)\n",
    "        self.debn0_3   = nn.BatchNorm2d(32)\n",
    "\n",
    "        self.classifier = nn.Conv2d(32, 2, kernel_size=1)\n",
    "\n",
    "    def forward(self, inputs):\n",
    "        # Layer 1\n",
    "        conv = self.layer1(inputs)\n",
    "        actv = F.relu(self.bn1(conv))\n",
    "        actv = self.attention1(actv)\n",
    "        \n",
    "        # Layer 2\n",
    "        conv = self.layer2(actv)\n",
    "        actv = F.relu(self.bn2(conv))\n",
    "        actv = self.attention2(actv)\n",
    "        \n",
    "        # Layer 3\n",
    "        conv1 = self.layer31(actv)\n",
    "        actv1 = F.relu(self.bn31(conv1))\n",
    "        conv2 = self.layer32(actv1)\n",
    "        bn = self.bn32(conv2)\n",
    "        res = torch.add(actv, bn)\n",
    "        res = self.attention3(res)\n",
    "        \n",
    "        # Layer 4\n",
    "        conv1 = self.layer41(res)\n",
    "        actv1 = F.relu(self.bn41(conv1))\n",
    "        conv2 = self.layer42(actv1)\n",
    "        bn = self.bn42(conv2)\n",
    "        res = torch.add(res, bn)\n",
    "        res = self.attention4(res)\n",
    "        \n",
    "        # Layer 5\n",
    "        conv1 = self.layer51(res)\n",
    "        actv1 = F.relu(self.bn51(conv1))\n",
    "        conv2 = self.layer52(actv1)\n",
    "        bn = self.bn52(conv2)\n",
    "        res = torch.add(res, bn)\n",
    "        res = self.attention5(res)\n",
    "        \n",
    "        # Layer 6\n",
    "        conv1 = self.layer61(res)\n",
    "        actv1 = F.relu(self.bn61(conv1))\n",
    "        conv2 = self.layer62(actv1)\n",
    "        bn = self.bn62(conv2)\n",
    "        res = torch.add(res, bn)\n",
    "        res = self.attention6(res)\n",
    "        \n",
    "        # Layer 7\n",
    "        conv1 = self.layer71(res)\n",
    "        actv1 = F.relu(self.bn71(conv1))\n",
    "        conv2 = self.layer72(actv1)\n",
    "        bn = self.bn72(conv2)\n",
    "        res = torch.add(res, bn)\n",
    "        res = self.attention7(res)\n",
    "        \n",
    "        # Layer 8\n",
    "        convs = self.layer81(res)\n",
    "        convs = self.bn81(convs)\n",
    "        conv1 = self.layer82(res)\n",
    "        actv1 = F.relu(self.bn82(conv1))\n",
    "        conv2 = self.layer83(actv1)\n",
    "        bn = self.bn83(conv2)\n",
    "        pool = self.pool1(bn)\n",
    "        res = torch.add(convs, pool)\n",
    "        \n",
    "        # Layer 9\n",
    "        convs = self.layer91(res)\n",
    "        convs = self.bn91(convs)\n",
    "        conv1 = self.layer92(res)\n",
    "        actv1 = F.relu(self.bn92(conv1))\n",
    "        conv2 = self.layer93(actv1)\n",
    "        bn = self.bn93(conv2)\n",
    "        pool = self.pool2(bn)\n",
    "        res = torch.add(convs, pool)\n",
    "        \n",
    "        # Layer 10\n",
    "        convs = self.layer101(res)\n",
    "        convs = self.bn101(convs)\n",
    "        conv1 = self.layer102(res)\n",
    "        actv1 = F.relu(self.bn102(conv1))\n",
    "        conv2 = self.layer103(actv1)\n",
    "        bn = self.bn103(conv2)\n",
    "        pool = self.pool1(bn)\n",
    "        res = torch.add(convs, pool)\n",
    "        \n",
    "        # Layer 11\n",
    "        convs = self.layer111(res)\n",
    "        convs = self.bn111(convs)\n",
    "        conv1 = self.layer112(res)\n",
    "        actv1 = F.relu(self.bn112(conv1))\n",
    "        conv2 = self.layer113(actv1)\n",
    "        bn = self.bn113(conv2)\n",
    "        pool = self.pool1(bn)\n",
    "        res = torch.add(convs, pool)\n",
    "        \n",
    "        # Layer 12\n",
    "        conv1 = self.layer121(res)\n",
    "        actv1 = F.relu(self.bn121(conv1))\n",
    "        conv2 = self.layer122(actv1)\n",
    "        bn = self.bn122(conv2)\n",
    "        \n",
    "        #最后一层特征图反卷积，使其大小与倒数第二层特征图一致(原图1/16)\n",
    "        x2_1 = F.relu(self.deconv2(bn)) \n",
    "        #倒数第二层特征图反卷积，使其大小与倒数第三层特征图一致(原图1/8)\n",
    "        x1_0 = F.relu(self.deconv1(x2_1))\n",
    "        \n",
    "        #倒数第三层特征图连续3次反卷积，使其大小与原始图像一致(由原图1/8到1/1)\n",
    "        x0_image = self.debn0_1(F.relu(self.deconv0_1(x1_0)))\n",
    "        x0_image = self.debn0_2(F.relu(self.deconv0_2(x0_image)))\n",
    "        x0_image = self.debn0_3(F.relu(self.deconv0_3(x0_image)))\n",
    "        outputs = self.classifier(x0_image)\n",
    "        return outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1d84f5e3",
   "metadata": {},
   "outputs": [],
   "source": [
    "data1 = SRNet_dataset('train_data1.csv')\n",
    "SRNet_dataloader1 = DataLoader(data1,batch_size = 16,shuffle = True)\n",
    "\n",
    "data2 = SRNet_dataset('train_data2.csv')\n",
    "SRNet_dataloader2 = DataLoader(data2,batch_size = 16,shuffle = True)\n",
    "\n",
    "data3 = SRNet_dataset('train_data3.csv')\n",
    "SRNet_dataloader3 = DataLoader(data3,batch_size = 16,shuffle = True)\n",
    "\n",
    "model = torch.load('')\n",
    "model = model.cuda()\n",
    "\n",
    "#model = Srnet().cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b039792",
   "metadata": {},
   "outputs": [],
   "source": [
    "#网络损失函数定义为交叉熵函数\n",
    "Loss_function1 = focal_loss(model = 1, alpha = 0.05).cuda()\n",
    "Loss_function2 = focal_loss(model = 2, alpha = 0.33).cuda()\n",
    "Loss_function3 = focal_loss(model = 3, alpha = 0.86).cuda()\n",
    "#网络优化方法为SGD\n",
    "optimizer = torch.optim.SGD(model.parameters(),lr = 0.001,momentum = 0.9)\n",
    "#os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"-1\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ef3cb163",
   "metadata": {},
   "outputs": [],
   "source": [
    "# epoch代表遍历完所有样本的过程，将epoch设置100，即遍历完样本100次\n",
    "for epoch in range(32):\n",
    "    Lossvalue = 0\n",
    "    Accvalue = 0\n",
    "    count = 0\n",
    "    s_epoch = str(epoch + 18)\n",
    "    for state1 in range(1):\n",
    "        for i, sample in enumerate(SRNet_dataloader1, 0):\n",
    "\n",
    "            images, labels = sample['image'], sample['label']\n",
    "            \n",
    "            device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "            images.to(device)\n",
    "            images = images.cuda()\n",
    "            labels = labels.cuda()\n",
    "            outputs = model(images)\n",
    "            _, predicts = torch.max(outputs, 1)\n",
    "\n",
    "            correct = (predicts == labels).sum().item()\n",
    "            total = (predicts != labels).sum().item() + correct\n",
    "            optimizer.zero_grad()\n",
    "        \n",
    "            loss = 0\n",
    "            for l in range(16):\n",
    "                tempout0 = outputs[l][0]\n",
    "                tempout1 = outputs[l][1]\n",
    "            \n",
    "                tempout0 = tempout0.reshape(-1,1)\n",
    "                tempout1 = tempout1.reshape(-1,1)\n",
    "                tempoutput = torch.cat([tempout0, tempout1], 1)\n",
    "            \n",
    "                templabel = labels[l]\n",
    "                templabel = templabel.reshape(-1,1)\n",
    "            \n",
    "                loss = loss + Loss_function1(tempoutput, templabel.long())\n",
    "                \n",
    "            loss = loss / 16   \n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "    \n",
    "            Lossvalue = Lossvalue + loss.item()\n",
    "            count = count + 1\n",
    "            Acc = correct / total\n",
    "            Accvalue = Accvalue + Acc\n",
    "            print('epoch is %d , state is 1 , %d times , loss is %f , acc is %f'%(epoch,i,loss.item(),Acc))\n",
    "                \n",
    "            if i % 40 == 0 and i != 280 and i != 0:\n",
    "                 for state2 in range(1):\n",
    "                    for j, sample in enumerate(SRNet_dataloader2, 0):\n",
    "\n",
    "                        images, labels = sample['image'], sample['label']\n",
    "                        \n",
    "                        device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "                        images.to(device)\n",
    "                        images = images.cuda()\n",
    "                        labels = labels.cuda()\n",
    "                        outputs = model(images)\n",
    "                        _, predicts = torch.max(outputs, 1)\n",
    "\n",
    "                        correct = (predicts == labels).sum().item()\n",
    "                        total = (predicts != labels).sum().item() + correct\n",
    "                        optimizer.zero_grad()\n",
    "        \n",
    "                        loss = 0\n",
    "                        for l in range(16):\n",
    "                            tempout0 = outputs[l][0]\n",
    "                            tempout1 = outputs[l][1]\n",
    "            \n",
    "                            tempout0 = tempout0.reshape(-1,1)\n",
    "                            tempout1 = tempout1.reshape(-1,1)\n",
    "                            tempoutput = torch.cat([tempout0, tempout1], 1)\n",
    "            \n",
    "                            templabel = labels[l]\n",
    "                            templabel = templabel.reshape(-1,1)\n",
    "            \n",
    "                            loss = loss + Loss_function2(tempoutput, templabel.long())\n",
    "\n",
    "                        loss = loss / 16\n",
    "                    \n",
    "                        loss.backward()\n",
    "                        optimizer.step()\n",
    "    \n",
    "                        Lossvalue = Lossvalue + loss.item()\n",
    "                        count = count + 1\n",
    "                        Acc = correct / total\n",
    "                        Accvalue = Accvalue + Acc\n",
    "                        print('epoch is %d , state is 2 , %d times , loss is %f , acc is %f'%(epoch,j,loss.item(),Acc))\n",
    "                        \n",
    "                        if j % 10 == 0 and j != 0:\n",
    "                            for state3 in range(1):\n",
    "                                for k, sample in enumerate(SRNet_dataloader3, 0):\n",
    "\n",
    "                                    images, labels = sample['image'], sample['label']\n",
    "                                    \n",
    "                                    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "                                    images.to(device)\n",
    "                                    images = images.cuda()\n",
    "                                    labels = labels.cuda()\n",
    "                                    outputs = model(images)\n",
    "                                    _, predicts = torch.max(outputs, 1)\n",
    "                        \n",
    "                                    correct = (predicts == labels).sum().item()\n",
    "                                    total = (predicts != labels).sum().item() + correct\n",
    "                                    optimizer.zero_grad()\n",
    "                                \n",
    "                                    loss = 0\n",
    "                                    for l in range(16):\n",
    "                                        tempout0 = outputs[l][0]\n",
    "                                        tempout1 = outputs[l][1]\n",
    "                                    \n",
    "                                        tempout0 = tempout0.reshape(-1,1)\n",
    "                                        tempout1 = tempout1.reshape(-1,1)\n",
    "                                        tempoutput = torch.cat([tempout0, tempout1], 1)\n",
    "                                    \n",
    "                                        templabel = labels[l]\n",
    "                                        templabel = templabel.reshape(-1,1)\n",
    "                                    \n",
    "                                        loss = loss + Loss_function3(tempoutput, templabel.long())\n",
    "                        \n",
    "                                    loss = loss / 16\n",
    "                            \n",
    "\n",
    "                                    loss.backward()\n",
    "                                    optimizer.step()\n",
    "                                \n",
    "                                    Lossvalue = Lossvalue + loss.item()\n",
    "                                    count = count + 1\n",
    "                                    Acc = correct / total\n",
    "                                    Accvalue = Accvalue + Acc\n",
    "                                    print('epoch is %d , state is 3 , %d times , loss is %f , acc is %f'%(epoch,k,loss.item(),Acc))\n",
    "            \n",
    "    Lossvalue = Lossvalue / count\n",
    "    Accvalue = Accvalue / count\n",
    "    print('epoch is %d , All_loss is %f , All_Acc is %f'%(epoch,Lossvalue,Accvalue))\n",
    "    path = '' + s_epoch + '.pt'\n",
    "    torch.save(model,path)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
